package com.agileai.hotweb.controller.core;

import java.util.List;

import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.bizmoduler.core.TreeManage;
import com.agileai.hotweb.domain.TreeBuilder;
import com.agileai.hotweb.domain.TreeModel;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.LocalRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.util.ListUtil;
import com.agileai.util.MapUtil;
import com.agileai.util.StringUtil;

public abstract class TreeManageHandler extends BaseHandler{
	protected String nodeIdField = "";
	protected String nodePIdField = "";
	protected String moveUpErrorMsg = "该节点是第一个节点，不能上移！";
	protected String moveDownErrorMsg = "该节点是最后一个节点，不能下移！";
	protected String deleteErrorMsg = "该节点还有子节点，不能删除！";
	
	public TreeManageHandler(){
		super();
	}
	abstract protected TreeBuilder provideTreeBuilder(DataParam param);
	abstract protected void processPageAttributes(DataParam param);
	abstract protected boolean isRootNode(DataParam param);
	abstract protected String provideDefaultNodeId(DataParam param);
	
	public ViewRenderer prepareDisplay(DataParam param) {
		String nodeId = param.get(this.nodeIdField);
		if (StringUtil.isNullOrEmpty(nodeId)){
			nodeId = provideDefaultNodeId(param);
		}
		TreeBuilder treeBuilder = provideTreeBuilder(param);
		TreeModel treeModel = treeBuilder.buildTreeModel();
		
		TreeManage service = this.getService();
		DataParam queryParam = new DataParam(this.nodeIdField,nodeId);
		DataRow record = service.queryCurrentRecord(queryParam);
		this.setAttributes(record);	
		this.processPageAttributes(param);
		this.setAttribute(this.nodeIdField, nodeId);
		this.setAttribute("isRootNode",String.valueOf(isRootNode(param)));
		
		String menuTreeSyntax = this.getTreeSyntax(param,treeModel,new StringBuffer());
		this.setAttribute("menuTreeSyntax", menuTreeSyntax);
		return new LocalRenderer(getPage());
	}
	
	protected String getTreeSyntax(DataParam param,TreeModel treeModel,StringBuffer treeSyntax){
    	String result = null;
    	try {
    		treeSyntax.append("<script type='text/javascript'>");
    		treeSyntax.append("d = new dTree('d');");
            String rootId = treeModel.getId();
            String rootName = treeModel.getName();
            treeSyntax.append("d.add('"+rootId+"',-1,'"+rootName+"',\"javascript:doRefresh('"+rootId+"')\");");
            treeSyntax.append("\r\n");
            buildTreeSyntax(treeSyntax,treeModel);
            treeSyntax.append("\r\n");
            treeSyntax.append("document.write(d);");
            treeSyntax.append("\r\n");
            String currentNodeId = this.getAttributeValue(this.nodeIdField);
            treeSyntax.append("d.s(d.getIndex('").append(currentNodeId).append("'));");
            treeSyntax.append("\r\n");            	
    		treeSyntax.append("</script>");
    		result = treeSyntax.toString();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
    }
	
	protected void buildTreeSyntax(StringBuffer treeSyntax,TreeModel treeModel){
		List<TreeModel> children = treeModel.getChildren();
		String parentId = treeModel.getId();
        for (int i=0;i < children.size();i++){
        	TreeModel child = children.get(i);
            String curNodeId = child.getId();
            String curNodeName = child.getName();
            if (!ListUtil.isNullOrEmpty(child.getChildren())){
            	treeSyntax.append("d.add('"+curNodeId+"','"+parentId+"','"+curNodeName+"',\"javascript:doRefresh('"+curNodeId+"')\");");
            	treeSyntax.append("\r\n");
            }else{
            	treeSyntax.append("d.add('"+curNodeId+"','"+parentId+"','"+curNodeName+"',\"javascript:doRefresh('"+curNodeId+"')\");");
            	treeSyntax.append("\r\n");
            }
            this.buildTreeSyntax(treeSyntax,child);
        }
    }
	public ViewRenderer doRefreshAction(DataParam param){
		return prepareDisplay(param);
	}
	public ViewRenderer doSaveAction(DataParam param){
		getService().updateCurrentRecord(param);
		return prepareDisplay(param);
	}
	public ViewRenderer doInsertChildAction(DataParam param){
		getService().insertChildRecord(param);
		return prepareDisplay(param);
	}
	public ViewRenderer doCheckUniqueAction(DataParam param){
		String responseText = "";
		String operateType = param.get(OperaType.KEY);
		DataParam queryParam = new DataParam();
		queryParam.append(param);
		queryParam.remove(this.nodeIdField);
		if (OperaType.CREATE.equals(operateType)){
			String uniqueField = this.getService().getUniqueField();
			queryParam.put(uniqueField,param.get("CHILD_"+uniqueField));
			DataRow record = getService().queryCurrentRecord(queryParam);
			if (!MapUtil.isNullOrEmpty(record)){
				responseText = defDuplicateMsg;
			}
		}else if (OperaType.UPDATE.equals(operateType)){
			DataRow record = getService().queryCurrentRecord(queryParam);
			String nodeId = param.get(nodeIdField);
			if (!MapUtil.isNullOrEmpty(record) && !nodeId.equals(record.stringValue(nodeIdField))){
				responseText = defDuplicateMsg;
			}
		}
		return new AjaxRenderer(responseText);
	}
	public ViewRenderer doCopyCurrentAction(DataParam param){
		String nodeId = param.get(this.nodeIdField);
		getService().copyCurrentRecord(nodeId);
		return prepareDisplay(param);
	}	
	public ViewRenderer doMoveUpAction(DataParam param){
		boolean isFirst = getService().isFirstChild(param);
		if (isFirst){
			setErrorMsg(this.moveUpErrorMsg);
		}else{
			String nodeId = param.get(this.nodeIdField);
			getService().changeCurrentSort(nodeId, true);
		}
		return prepareDisplay(param);
	}
    public ViewRenderer doChangeParentAction(DataParam param){
    	String responseText = FAIL;
    	String nodeId = param.get(this.nodeIdField);
    	DataParam queryParam = new DataParam(this.nodeIdField,nodeId);
    	DataRow row = this.getService().queryCurrentRecord(queryParam);
    	row.put(nodePIdField,param.get(this.nodePIdField));
    	this.getService().updateCurrentRecord(row.toDataParam(true));
    	responseText = SUCCESS;
    	return new AjaxRenderer(responseText);
    }	
	public ViewRenderer doMoveDownAction(DataParam param){
		boolean isLast = getService().isLastChild(param);
		if (isLast){
			setErrorMsg(this.moveDownErrorMsg);
		}else{
			String nodeId = param.get(this.nodeIdField);
			getService().changeCurrentSort(nodeId, false);
		}		
		return prepareDisplay(param);
	}
	public ViewRenderer doDeleteAction(DataParam param){
		String nodeId = param.get(this.nodeIdField);
		List<DataRow> childRecords = getService().queryChildRecords(nodeId);
		if (ListUtil.isNullOrEmpty(childRecords)){
			getService().deleteCurrentRecord(nodeId);
			param.remove(this.nodeIdField);
			param.put(this.nodeIdField,param.get(this.nodePIdField));
		}else{
			this.setErrorMsg(deleteErrorMsg);
		}
		return prepareDisplay(param);
	}

	protected TreeManage getService(){
		return (TreeManage)this.lookupService(serviceId);
	}
}
